package app.ui;

import game.components.AppUtilities;
import game.components.Player;
import game.components.TableChess;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;

import javax.swing.JPanel;

public class PlayAreaPanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected PlayingScreenUi mPanel;
	protected TableChess tableChess;

	protected int xDisp = 0; // the position of top corner on tableChess
	protected int yDisp = 0; // the position of top corner on tableChess
	protected boolean flagChangingX = true;
	protected boolean flagChangingY = true;

	private Point curMouLoc = new Point(); // current mouse location on table
	private Point lasMovLoc; // last moving location on table

	private Player player1;
	private Player player2;

	public PlayAreaPanel(PlayingScreenUi mPanel) {
		super(null);
		this.mPanel = mPanel;
		this.tableChess = new TableChess(getAppUtilities());

		this.player1 = getAppUtilities().getPlayer1();
		this.player2 = getAppUtilities().getPlayer2();

		this.setBackground(getAppUtilities().getBg_playingArea());
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);

		Graphics2D g2D = (Graphics2D) g;

		doDrawGrid(g2D);
		doDrawHighlight(g2D);
		doDraw_X_O(g2D);
	}

	private synchronized void doDrawHighlight(Graphics2D g) {
		if (isScrolling() || !getAppUtilities().isGameStatus()) {
			return;
		}

		// highlight current mouse position
		g.setColor(getAppUtilities().getBg_highlightMousePointing());
		int cellSize = getAppUtilities().getCellSize();
		int x = curMouLoc.x * cellSize + 1;
		int y = curMouLoc.y * cellSize + 1;
		int width = cellSize - 1;

		g.fillRect(x, y, width, width);

		// highlight last moving
		if (lasMovLoc == null) {
			return;
		}
		g.setColor(getAppUtilities().getHlLastMoving());
		x = lasMovLoc.x * cellSize + 1;
		y = lasMovLoc.y * cellSize + 1;

		g.fillRect(x, y, width, width);
	}

	private synchronized void doDraw_X_O(Graphics2D g2d) {
		// draw X --------------------------------------------------------------
		g2d.setColor(getAppUtilities().getX_Color());

		int length1 = player1.getMoveCollection().size();
		if (length1 > 0) {
			for (Point p : player1.getMoveCollection()) {
				tableChess.draw_O(g2d, p);
			}
		}
		// end draw X ----------------------------------------------------------

		// draw O --------------------------------------------------------------
		g2d.setColor(getAppUtilities().getO_Color());

		int length2 = player2.getMoveCollection().size();
		if (length2 > 0) {
			for (Point p : player2.getMoveCollection()) {
				tableChess.draw_O(g2d, p);
			}
		}
		// end draw O ----------------------------------------------------------
	}

	private synchronized void doDrawGrid(Graphics2D g) {
		int cellSize = getAppUtilities().getCellSize();
		g.setColor(getAppUtilities().getGridColor());

		int height = getHeight();
		int width = getWidth();
		int x = this.xDisp % cellSize;

		for (int colLine = x; colLine <= width; colLine += cellSize) {
			g.drawLine(colLine, 0, colLine, height);
		}

		for (int rowLine = x; rowLine <= height; rowLine += cellSize) {
			g.drawLine(0, rowLine, width, rowLine);
		}
	}

	public void adjustXY_disp(int xDisp, int yDisp) {
		flagChangingX = false;
		flagChangingY = false;
		xDisp = checkValue(xDisp, getWidth());
		yDisp = checkValue(yDisp, getHeight());

		if (xDisp != this.xDisp) {
			this.xDisp = xDisp;
			flagChangingX = true;
		}
		if (yDisp != this.yDisp) {
			this.yDisp = yDisp;
			flagChangingY = true;
		}

		if (flagChangingX || flagChangingY) {
			setScrolling(true);
			this.repaint();
			// System.out.println("(x, y) = " + "(" + xDisp + ", " + yDisp +
			// ")");
		}
	}

	protected int checkValue(int iVal, int setMax) {
		if (iVal < 0) {
			iVal = 0;
		}

		int maxVal = tableChess.getSize() - setMax / getAppUtilities().getCellSize();

		if (iVal > maxVal) {
			iVal = maxVal;
		}

		return iVal;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	public PlayingScreenUi getmPanel() {
		return mPanel;
	}

	public AppUtilities getAppUtilities() {
		return mPanel.getmFrame().getAppUtilities();
	}

	public TableChess getTableChess() {
		return tableChess;
	}

	public int getxDisp() {
		return xDisp;
	}

	public int getyDisp() {
		return yDisp;
	}

	public boolean isFlagChangingX() {
		return flagChangingX;
	}

	public boolean isFlagChangingY() {
		return flagChangingY;
	}

	public Player getPlayer1() {
		return player1;
	}

	public Player getPlayer2() {
		return player2;
	}

	public Point getCurMouLoc() {
		return curMouLoc;
	}

	public void setCurMouLoc(Point curMouLoc) {
		if (this.curMouLoc != curMouLoc) {
			this.curMouLoc = curMouLoc;
			this.repaint();
		}
	}

	public boolean isScrolling() {
		return mPanel.getMouseAction().isScrolling();
	}

	public void setScrolling(boolean scrolling) {
		mPanel.getMouseAction().setScrolling(scrolling);
	}

	public void setLasMovLoc(Point lasMovLoc) {
		this.lasMovLoc = lasMovLoc;
	}

	public void clearScreen() {
		getAppUtilities().resetGame();
		this.repaint();
	}
}
